package cn.net.autocode.platform.excel;

import cn.hutool.core.util.StrUtil;
import cn.net.autocode.core.bean.ResultT;
import cn.net.autocode.files.excel.ExcelTools;
import cn.net.autocode.platform.excel.service.ExcelServ;
import cn.net.autocode.platform.excel.vo.ExcelFile;
import cn.net.autocode.platform.exception.PlatformQueryException;
import cn.net.autocode.platform.factory.SpringBeanFactory;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("autocode/excelProvider")
public class ExcelProviderCtrl implements ApplicationListener<ApplicationReadyEvent> {

    private final ExcelServ excelServ;

    private final Map<String, ExcelTemplate> excelTemplates = new HashMap<>();

    public ExcelProviderCtrl(ExcelServ excelServ) {
        this.excelServ = excelServ;
    }

    @RequestMapping("excelImport")
    @Transactional
    @ResponseBody
    public ResultT excelImport(@RequestParam MultipartFile file, HttpServletRequest request) throws IOException, PlatformQueryException {
        String templateCode = request.getParameter("templateCode");
        if(StrUtil.isBlank(templateCode)){
            return ResultT.fail("templateCode不能为空！");
        }

        //获取参数信息
        Map<String,String[]> paramMap = request.getParameterMap();
        JSONObject param = new JSONObject();
        for(Map.Entry<String,String[]> entry:paramMap.entrySet()){
            String[] values = entry.getValue();
            if(values.length==1){
                param.put(entry.getKey(), values[0]);
            }else if(values.length>1){
                param.put(entry.getKey(), values);
            }
        }

        //解析excel数据
        JSONArray array = ExcelTools.readExcel(file.getInputStream());

        //解析表头
        JSONObject template = excelServ.excelReadTemplate(templateCode,array);

        //转化为表数据
        JSONArray dataArray = excelServ.parseExcelData(template,array);

        //保存数据
        if (this.excelTemplates.containsKey(templateCode)) {
            this.excelTemplates.get(templateCode).importExcel(template,dataArray,param);
        }else{
            excelServ.dataSave(template,dataArray);
        }

        return ResultT.success();
    }

    @RequestMapping("excelExport")
    @ResponseBody
    public ResponseEntity<byte[]> excelExport(@RequestBody JSONObject param) {
        String templateCode = param.getString("templateCode");
        if(StrUtil.isBlank(templateCode)){
            throw new RuntimeException("templateCode不能为空！");
        }

        //模板表头
        JSONObject template = excelServ.excelTemplate(templateCode);
        //保存数据
        if (this.excelTemplates.containsKey(templateCode)) {
            ExcelFile excelFile = this.excelTemplates.get(templateCode).exportExcel(param);

            byte[] bytes = ExcelTools.writeExcel(template,excelFile.getDataArray());

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.add("file-name", URLEncoder.encode(excelFile.getFileName(), StandardCharsets.UTF_8));
            headers.setContentDispositionFormData("attachment", URLEncoder.encode(excelFile.getFileName(), StandardCharsets.UTF_8));
            return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
        }else{
            throw new RuntimeException("templateCode没有定义数据导出脚本！");
        }
    }

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        List<ExcelTemplate> beans = SpringBeanFactory.getBeansByType(ExcelTemplate.class);
        for(ExcelTemplate bean:beans){
            ExcelTemplateAnnotation beanAnnotation = bean.getClass().getAnnotation(ExcelTemplateAnnotation.class);
            if (beanAnnotation != null) {
                String templateCode = beanAnnotation.value();
                if(this.excelTemplates.containsKey(templateCode)){
                    throw new RuntimeException("系统中存在多个Excel导入导出模板【"+templateCode+"】的处理脚本！");
                }else{
                    this.excelTemplates.put(templateCode,bean);
                }
            }

        }
    }
}
